#pragma once
#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <fstream>

// 插值多项式抽象基类
class PolynomialInterpolation
{
public:
    PolynomialInterpolation() = default;

    PolynomialInterpolation(const std::vector<double> &ips, int np)
        : interpolation_points{ips}, n{np} {}

    virtual ~PolynomialInterpolation() = 0; // 纯虚析构函数

protected:
    std::vector<double> interpolation_points; // 插值点
    int n;                                    // 多项式阶数
};

// 牛顿插值多项式
class NewtonInterpolation : public PolynomialInterpolation
{
public:
    double evaluate(double x) const; // 计算插值多项式在x的函数值

    void print(double left, double right, double grid = 0.01) const; // 打印区间[left，right]内的插值函数

    void output_file(const char *filename, const double left, const double right,
                     const double grid = 0.01) const; // 将区间[left，right]内的插值函数输出到txt文件中

    NewtonInterpolation() = default;

    /// @brief 给定函数和插值点，用多项式逼近函数
    /// @param f 被逼近函数
    /// @param ips 插值点
    NewtonInterpolation(const std::vector<double> &ips, int np, double (*f)(double));

    /// @brief 给定插值点和函数在插值点的值，用多项式逼近函数
    /// @param ivs 函数在插值点的值
    /// @param ips 插值点
    NewtonInterpolation(const std::vector<double> &ips, int np, const std::vector<double> &ivs);

    ~NewtonInterpolation() = default;

protected:
    virtual void calculate(); // 根据newton插值法计算差商表

    std::vector<std::vector<double>> divided_differences_table; // 差商表
};

// 基于牛顿插值的切比雪夫插值多项式
class ChebyshevInterpolation : public NewtonInterpolation
{
public:
    /// @brief 给定函数和多项式的阶数，用多项式逼近函数
    /// @param f 函数在插值点的值
    /// @param n 多项式的阶数
    ChebyshevInterpolation(int np, double (*f)(double));

    ~ChebyshevInterpolation() = default;
};

class HermiteInterpolation : public NewtonInterpolation
{
public:
    double diff(double x, double eps = 1e-5) const;

    /// @brief 给定插值点，阶数信息和函数在插值点的值及导数值，用多项式逼近函数
    /// @param ips 插值点
    /// @param order 对应插值点的导函数最高阶数
    /// @param ivs 函数在插值点的值及相应阶数的导数值
    HermiteInterpolation(const std::vector<double> &ips, const std::vector<int> &order,
                         const std::vector<std::vector<double>> &ivs);

    ~HermiteInterpolation() = default;

private:
    void calculate() override; // 计算差商表，覆盖父类中的calculate()函数
};